package zoo.lock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author CKC
 * @date 2022/11/15 21:14
 */
public class CuratorLockTest {
    static CuratorFramework curatorFramework;


    public static void main(String[] args) throws InterruptedException {
        getCuratorFramework();
        System.out.println("启动成功");
        InterProcessMutex interProcessMutex = new InterProcessMutex(curatorFramework, "/locks");
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000));
        Ticket ticket = new Ticket(2000);
        for (int i = 0; i < 1000; i++) {
            threadPoolExecutor.execute(() -> {
                try {
                    interProcessMutex.acquire();
                    System.out.println(Thread.currentThread().getName() + "  获取到锁");
                    ticket.num--;
                    ticket.num--;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {
                    try {
                        interProcessMutex.release();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        Thread.sleep(20000);
        System.out.println("------   " + ticket.num);


    }

    private static void getCuratorFramework() {
        CuratorFramework build = CuratorFrameworkFactory.builder().connectString("192.168.3.55:2181")
                .connectionTimeoutMs(2000)
                .sessionTimeoutMs(2000)
                .retryPolicy(new ExponentialBackoffRetry(3000, 3))
                .build();
        build.start();
        curatorFramework = build;
    }

    static class Ticket {
        public Integer num = 1000;

        public Ticket(Integer num) {
            this.num = num;
        }
    }

}
